import unittest
from unittest.mock import MagicMock, patch

# 将项目根目录添加到 sys.path
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from src.stk_utils import STKUtils, Satellite, Vessel, SensorSAR

print(sys.path)

class TestSTKUtils(unittest.TestCase):
    @patch('comtypes.client.CreateObject')
    @patch('comtypes.client.GetActiveObject')
    def setUp(self, mock_get_active, mock_create):
        # Mock STK application
        self.mock_stk = MagicMock()
        mock_get_active.side_effect = Exception()
        mock_create.return_value = self.mock_stk
        
        # Mock scenario
        self.mock_scenario = MagicMock()
        self.mock_stk.Personality2.CurrentScenario = None
        def set_current_scenario(name):
            self.mock_stk.Personality2.CurrentScenario = self.mock_scenario
            return self.mock_scenario
        self.mock_stk.Personality2.NewScenario.side_effect = set_current_scenario
        
        # Mock config
        self.mock_sat_config = {
            'name': 'TestSat',
            'type': 'satellite',
            'basic': {
                'orbit': {
                    'propagator': 'ePropagatorTwoBody',
                    'semi_major_axis': 7000,
                    'eccentricity': 0.01,
                    'inclination': 45,
                    'raan': 0,
                    'arg_perigee': 0,
                    'true_anomaly': 0
                }
            }
        }

        self.mock_vessel_config = {
            'name': 'TestVessel',
            'type': 'vessel',
            'basic': {
                'route': {
                    'waypoints': [
                        {
                            'latitude': 30.61726503,
                            'longitude': 121.30747049,
                            'altitude': 0,
                            'speed': 0.015
                        }
                    ]
                }
            }
        }
        
        # Initialize STKUtils with scenario name only
        self.stk_utils = STKUtils('TestScenario')
        # Mock scenario path
        self.stk_utils.scenario_path = 'test_path'

    def test_create_object_satellite(self):
        # Mock satellite creation
        mock_satellite = MagicMock()
        self.mock_scenario.Children.New.return_value = mock_satellite
        
        # Test satellite creation
        sat = self.stk_utils.create_object(self.mock_sat_config)
        self.assertIsNotNone(sat)
        self.mock_scenario.Children.New.assert_called_once()

    def test_create_object_vessel(self):
        # Mock vessel creation
        mock_vessel = MagicMock()
        self.mock_scenario.Children.New.return_value = mock_vessel
        
        # Test vessel creation
        vessel = self.stk_utils.create_object(self.mock_vessel_config)
        self.assertIsNotNone(vessel)
        self.mock_scenario.Children.New.assert_called_once()

    def test_add_sensor(self):
        # Mock satellite
        mock_satellite = 'TestSat'
        
        # Mock sensor config
        sensor_config = {
            'type': 'SAR',
            'name': 'TestSensor',
            'params': {
                'elevation_angles_min': 20,
                'elevation_angles_max': 60,
                'exclusion_angle_forward': 30,
                'exclusion_angle_aft': 30
            }
        }
        
        # Test sensor addition
        result = self.stk_utils.add_sensor(mock_satellite, sensor_config)
        self.assertTrue(result)
        self.stk_utils.stk.Personality2.ExecuteCommand.assert_called()

    def test_save_scenario(self):
        # Mock save scenario
        self.mock_stk.Personality2.SaveAs.return_value = True
        save_folder = '\\test_path'
        # Test scenario save
        result = self.stk_utils.save_scenario(save_folder)
        self.assertTrue(result)
        self.mock_stk.Personality2.SaveAs.assert_called_once_with('\\test_path')

class TestSatellite(unittest.TestCase):
    def setUp(self):
        self.mock_scenario = MagicMock()
        self.mock_satellite = MagicMock()
        self.mock_scenario.Children.New.return_value = self.mock_satellite
        
        self.mock_config = {
            'name': 'TestSat',
            'type': 'satellite',
            'basic': {
                'orbit': {
                    'propagator': 'ePropagatorTwoBody',
                    'semi_major_axis': 7000,
                    'eccentricity': 0.01,
                    'inclination': 45,
                    'raan': 0,
                    'arg_perigee': 0,
                    'true_anomaly': 0
                }
            }
        }

    def test_create(self):
        satellite = Satellite()
        sat = satellite.create(self.mock_scenario, 'TestSat', self.mock_config)
        self.assertIsNotNone(sat)
        self.mock_scenario.Children.New.assert_called_once()

class TestVessel(unittest.TestCase):
    def setUp(self):
        self.mock_scenario = MagicMock()
        self.mock_vessel = MagicMock()
        self.mock_scenario.Children.New.return_value = self.mock_vessel
        
        self.mock_config = {
            'name': 'TestVessel',
            'type': 'vessel',
            'basic': {
                'route': {
                    'waypoints': [
                        {
                            'latitude': 30.61726503,
                            'longitude': 121.30747049,
                            'altitude': 0,
                            'speed': 0.015
                        }
                    ]
                }
            }
        }

    def test_create(self):
        vessel = Vessel()
        ves = vessel.create(self.mock_scenario, 'TestVessel', self.mock_config)
        self.assertIsNotNone(ves)
        self.mock_scenario.Children.New.assert_called_once()

class TestSensor(unittest.TestCase):
    def setUp(self):
        self.parent = 'TestSat'
        self.attached = 'TestSensor'

        self.mock_root = MagicMock()
        self.mock_config = {
            'type': 'SAR',
            'name': self.attached,
            'params': {
                'elevation_angles_min': 20,
                'elevation_angles_max': 60,
                'exclusion_angle_forward': 30,
                'exclusion_angle_aft': 30
                }
        }

    def test_attach(self):
        sensor = SensorSAR()
        result = sensor.attach(self.parent, self.mock_config, self.mock_root)
        self.assertTrue(result)
        self.mock_root.ExecuteCommand.assert_called()

if __name__ == '__main__':
    unittest.main()
